﻿Imports System.Drawing.Drawing2D
Imports System.Windows.Forms
'Imports MyLib.WindowsForms.Properties

Public Module Styles

#Region "Enumérations"
    Public Enum etatComposant
        Enabled
        Disabled
        MouseOver
    End Enum
#End Region

#Region "Variables privées"

    Private _Singleton As StylesCouleurs
    Private _SingletonProtection As New [Object]()

    Private _Font_Title_Frm As Font = New System.Drawing.Font("Arial", 14, System.Drawing.FontStyle.Bold)
    Private _Font_Title_Panel As Font = New System.Drawing.Font("Arial", 13.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, 0)
    Private _Font_Title_BoutonOutlook As Font = New System.Drawing.Font("Arial", 9.75F, System.Drawing.FontStyle.Bold)

#End Region

#Region "Creation d'une instance pour le thème par défaut"

    Public ReadOnly Property Instance() As StylesCouleurs
        Get
            'Test si on a un Doubleton
            If _Singleton Is Nothing Then
                'Protection multi-thread
                SyncLock _SingletonProtection
                    If _Singleton Is Nothing Then
                        'Création du Doubleton
                        _Singleton = New StylesCouleurs()
                    End If
                End SyncLock
            End If
            'Retour du Doubleton
            Return _Singleton
        End Get
    End Property

#End Region

#Region "Propriétés"

    Public ReadOnly Property FontTitleFrm() As Font
        Get
            Return _Font_Title_Frm
        End Get
    End Property

    Public ReadOnly Property FontTitlePanel() As Font
        Get
            Return _Font_Title_Panel
        End Get
    End Property

    Public ReadOnly Property FontTitleBoutonOutlook() As Font
        Get
            Return _Font_Title_BoutonOutlook
        End Get
    End Property

#End Region

#Region "Affichage des couleurs des thèmes"

    'Permet d'afficher les couleurs du thème en cours
    Public Sub afficherThemes()
        StylesCouleurs.Montrer()
    End Sub

#End Region

#Region "Thèmes de remplissage"

    Public Sub PaintGlossyVista(ByVal graphics As Graphics, ByVal zone As Rectangle)
        PaintGlossyVista(graphics, zone, Nothing)
    End Sub

    ''' <summary>
    ''' Style glossy à la Vista
    ''' </summary>
    ''' <param name="graphics"></param>
    ''' <param name="zone"></param>
    ''' <param name="masque"></param>
    Public Sub PaintGlossyVista(ByVal graphics As Graphics, ByVal zone As Rectangle, ByVal masque As GraphicsPath)

        If graphics Is Nothing Then
            'Erreurs.Enregistrer("Argument non défini.", False)
            Exit Sub
        End If

        Dim Int_Diametre As Int32 = Convert.ToInt32(zone.Height / 2)

        Dim Rect_angle As New Rectangle(zone.Location, New Size(Int_Diametre, Int_Diametre))
        Dim Rect1 As Rectangle, Rect2 As Rectangle

        Dim Path As New GraphicsPath()

        'on ne travail que sur la partie haute du control
        Rect1 = New Rectangle(zone.X, zone.Y, zone.Width, Convert.ToInt32(zone.Height / 2) + 1)
        Rect2 = New Rectangle(Rect1.X, Rect1.Y + Rect1.Height + 1, Rect1.Width, zone.Height - Rect1.Height)

        'Remplissage du gloss par un dégradé
        If masque Is Nothing Then
            'Création du path pour le gloss
            'ligne du haut
            Path.AddLine(Rect1.X, Rect1.Y, Rect1.X + Rect1.Width, zone.Y)
            'angle à droite
            Rect_angle.X = Rect1.X + Rect1.Width - Int_Diametre
            Rect_angle.Y = Rect1.Y + Rect1.Height - Int_Diametre
            Path.AddArc(Rect_angle, 0, 90)
            'angle gauche;
            Rect_angle.X = Rect1.X
            Path.AddArc(Rect_angle, 90, 90)
            'fermeture de la figure
            Path.CloseFigure()
            graphics.FillPath(New LinearGradientBrush(Rect1, Color.FromArgb(150, Color.White), Color.FromArgb(0, Color.White), LinearGradientMode.Vertical), Path)
        Else
            Dim R_Masque As New Region(masque)

            R_Masque.Intersect(Rect1)

            graphics.FillRegion(New LinearGradientBrush(Rect1, Color.FromArgb(150, Color.White), Color.FromArgb(0, Color.White), LinearGradientMode.Vertical), R_Masque)
            'Libération mémoire
            R_Masque.Dispose()
            R_Masque = Nothing
        End If

        '--------------------------------------------------------------------------------------------------
        'on ne travail que sur la partie basse du control
        If masque Is Nothing Then
            'Création du path pour le gloss
            Path = New GraphicsPath()
            'angle gauche
            Rect_angle.X = Rect2.X
            Rect_angle.Y = Rect2.Y
            Path.AddArc(Rect_angle, 180, 90)
            'angle à droite
            Rect_angle.X = Rect2.X + Rect2.Width - Int_Diametre
            Path.AddArc(Rect_angle, 270, 90)

            'ligne du bas
            Path.AddLine(Rect2.X + Rect2.Width, Rect2.Y + Rect2.Height, Rect2.X, Rect2.Y + Rect2.Height)
            'Fermeture de la figure
            Path.CloseFigure()

            Rect2.Y = Rect1.Y + Rect1.Height
            'Remplissage du gloss par un dégradé
            graphics.FillPath(New LinearGradientBrush(Rect2, Color.FromArgb(0, Color.Black), Color.FromArgb(100, Color.Black), LinearGradientMode.Vertical), Path)
        Else
            Dim R_Masque As New Region(masque)
            R_Masque.Intersect(Rect2)
            Rect2.Y = Rect1.Y + Rect1.Height
            'Remplissage du gloss par un dégradé
            graphics.FillRegion(New LinearGradientBrush(Rect2, Color.FromArgb(0, Color.Black), Color.FromArgb(100, Color.Black), LinearGradientMode.Vertical), R_Masque)
            R_Masque.Dispose()
            R_Masque = Nothing
        End If

        'Libérations mémoire
        If Path IsNot Nothing Then
            Path.Dispose()
        End If

        Path = Nothing
    End Sub

    ''' <summary>
    ''' Font type Aéro glass
    ''' </summary>
    ''' <param name="graphics">Zone graphique du contrôle à dessiner</param>
    ''' <param name="zone">Rectangle contenant la zone à colorier</param>
    ''' <param name="couleur">Couleur de base pour le dégradé AERO</param>
    ''' <param name="masque">Masque de la région à colorier à l'intérieur de la zone</param>
    Public Sub PaintBackAeroGlassOMANE(ByVal graphics As Graphics, ByVal zone As Rectangle, _
                                       ByVal couleur As Color, ByVal masque As GraphicsPath)

        Dim backColorDegrade11 As Color
        Dim backColorDegrade12 As Color
        Dim backColorDegrade21 As Color
        Dim backColorDegrade22 As Color

        backColorDegrade11 = Color.FromArgb(50, couleur)
        backColorDegrade12 = Color.FromArgb(160, couleur)
        backColorDegrade21 = Color.FromArgb(190, couleur)
        backColorDegrade22 = Color.FromArgb(210, couleur)

        PaintDoubleDegrade(graphics, zone, _
                           backColorDegrade11, _
                           backColorDegrade12, _
                           backColorDegrade21, _
                           backColorDegrade22, _
                           masque, 0.5)
    End Sub

    ''' <summary>
    ''' Font type Aéro glass
    ''' </summary>
    ''' <param name="graphics">Zone graphique du contrôle à dessiner</param>
    ''' <param name="zone">Rectangle définissant la zone à colorier</param>
    ''' <param name="couleur">Couleur de base pour le dégradé AERO</param>
    Public Sub PaintBackAeroGlassOMANE(ByVal graphics As Graphics, ByVal zone As Rectangle, _
                                   ByVal couleur As Color)
        PaintBackAeroGlassOMANE(graphics, zone, couleur, Nothing)
    End Sub

    ''' <summary>
    ''' Font de type double dégradé vertical
    ''' </summary>
    ''' <param name="graphics">Zone graphique sur laquelle on va dessiner</param>
    ''' <param name="zone">Rectangle définissant la zone à colorier</param>
    ''' <param name="backColorDegrade11">Couleur haute du premier dégradé</param>
    ''' <param name="backColorDegrade12">Couleur basse du premier dégradé</param>
    ''' <param name="backColorDegrade21">Couleur haute du deuxième dégradé</param>
    ''' <param name="backColorDegrade22">Couleur basse du deuxième dégradé</param>
    Public Sub PaintDoubleDegrade(ByVal graphics As Graphics, ByVal zone As Rectangle, _
                                  ByVal backColorDegrade11 As Color, _
                                  ByVal backColorDegrade12 As Color, _
                                  ByVal backColorDegrade21 As Color, _
                                  ByVal backColorDegrade22 As Color, _
                                  ByVal posAxeDegrade As Double)
        PaintDoubleDegrade(graphics, zone, _
                   backColorDegrade11, _
                   backColorDegrade12, _
                   backColorDegrade21, _
                   backColorDegrade22, _
                   Nothing, _
                   posAxeDegrade)
    End Sub

    ''' <summary>
    ''' Font de type double dégradé vertical
    ''' </summary>
    ''' <param name="graphics">Zone graphique à redessiner</param>
    ''' <param name="zone">Rectangle définissant la zone à l'intérieur de laquelle colorier</param>
    ''' <param name="backColorDegrade11">Couleur haute du premier dégradé</param>
    ''' <param name="backColorDegrade12">Couleur basse du premier dégradé</param>
    ''' <param name="backColorDegrade21">Couleur haute du deuxième dégradé</param>
    ''' <param name="backColorDegrade22">Couleur basse du deuxième dégradé</param>
    ''' <param name="masque">Masque de la région à colorier à l'intérieur de la zone</param>
    Public Sub PaintDoubleDegrade(ByVal graphics As Graphics, ByVal zone As Rectangle, _
                                  ByVal backColorDegrade11 As Color, _
                                  ByVal backColorDegrade12 As Color, _
                                  ByVal backColorDegrade21 As Color, _
                                  ByVal backColorDegrade22 As Color, _
                                  ByVal masque As GraphicsPath, ByVal posAxeDegrade As Double)

        'Ce fond est composé de 2 dégradés
        'Nettoyage de l'objet graphique
        'graphics.FillRegion(Brushes.White, New Region(masque))

        'Définition des brosses
        Dim brush1 As LinearGradientBrush = Nothing, brush2 As LinearGradientBrush = Nothing
        Dim Int_Height As Int32 = Convert.ToInt32(zone.Height * posAxeDegrade)
        Dim rect1 As Rectangle, rect2 As Rectangle

        Try

            If Int_Height <> 0 Then
                rect1 = New Rectangle(zone.X, zone.Y, zone.Width, Int_Height)
                brush1 = New LinearGradientBrush(rect1, backColorDegrade11, backColorDegrade12, LinearGradientMode.Vertical)
                brush1.WrapMode = WrapMode.TileFlipX

                If masque Is Nothing Then
                    graphics.FillRectangle(New SolidBrush(Color.White), rect1)
                    graphics.FillRectangle(brush1, rect1)
                Else
                    Dim r As Region = Nothing
                    'Avec masque
                    r = New Region(masque)
                    r.Intersect(rect1)
                    graphics.FillRegion(New SolidBrush(Color.White), r)
                    graphics.FillRegion(brush1, r)
                End If
            End If

            If zone.Height - Int_Height <> 0 Then
                'Mise en place du dégradé en bas
                rect2 = New Rectangle(zone.X, zone.Y + Int_Height, zone.Width, zone.Height - Int_Height)
                brush2 = New LinearGradientBrush(rect2, backColorDegrade22, backColorDegrade21, LinearGradientMode.Vertical)
                brush2.WrapMode = WrapMode.TileFlipX

                If masque Is Nothing Then
                    graphics.FillRectangle(New SolidBrush(Color.White), rect2)
                    graphics.FillRectangle(brush2, rect2)
                Else
                    Dim r As Region = Nothing
                    r = New Region(masque)
                    r.Intersect(rect2)
                    graphics.FillRegion(New SolidBrush(Color.White), r)
                    graphics.FillRegion(brush2, r)
                End If
            End If

        Catch
        Finally
            If brush1 IsNot Nothing Then
                brush1.Dispose()
            End If
            brush1 = Nothing
            If brush2 IsNot Nothing Then
                brush2.Dispose()
            End If
            brush2 = Nothing
        End Try

    End Sub

#End Region

#Region "Rectangle arrondis"
    Public Function GetRoundRectangle(ByVal zone As Rectangle, ByVal angle As Int32) As GraphicsPath
        Return GetRoundRectangle(zone, angle, angle, angle, angle)
    End Function
    Public Function GetRoundRectangle(ByVal zone As Rectangle, ByVal angleTopLeft As Int32, ByVal angleTopRight As Int32, ByVal angleBottomRight As Int32, ByVal angleBottomLeft As Int32) As GraphicsPath
        Dim path As GraphicsPath = Nothing
        Try
            path = New GraphicsPath()
            'Top right
            If angleTopLeft = 0 Then
                path.AddLine(zone.X, zone.Y, zone.X + 1, zone.Y)
            Else
                path.AddArc(zone.X, zone.Y, angleTopLeft, angleTopLeft, 180, 90)
            End If

            'Top left
            If angleTopRight = 0 Then
                path.AddLine(zone.X + zone.Width, zone.Y, zone.X + zone.Width, zone.Y + 1)
            Else
                path.AddArc(zone.X + zone.Width - angleTopRight, zone.Y, angleTopRight, angleTopRight, 270, 90)
            End If

            'Bottom right
            If angleBottomRight = 0 Then
                path.AddLine(zone.X + zone.Width, zone.Y + zone.Height, zone.X + zone.Width, zone.Y + zone.Height - 1)
            Else
                path.AddArc(zone.X + zone.Width - angleBottomRight, zone.Y + zone.Height - angleBottomRight, angleBottomRight, angleBottomRight, 0, 90)
            End If

            'Bottom left
            If angleBottomRight = 0 Then
                path.AddLine(zone.X, zone.Y + zone.Height, zone.X, zone.Y + zone.Height - 1)
            Else
                path.AddArc(zone.X, zone.Y + zone.Height - angleBottomLeft, angleBottomLeft, angleBottomLeft, 90, 90)
            End If

            path.CloseFigure()
            Return path
        Catch
            Return Nothing
        Finally
            path = Nothing
        End Try
    End Function
    Public Function GetRoundRectangle(ByVal left As Int32, ByVal top As Int32, ByVal width As Int32, ByVal height As Int32, ByVal angle As Int32) As GraphicsPath
        Return GetRoundRectangle(New Rectangle(left, top, width, height), angle, angle, angle, angle)
    End Function
    Public Function GetRoundRectangle(ByVal left As Int32, ByVal top As Int32, ByVal width As Int32, ByVal height As Int32, ByVal angleTopLeft As Int32, ByVal angleTopRight As Int32, _
     ByVal angleBottomRight As Int32, ByVal angleBottomLeft As Int32) As GraphicsPath
        Return GetRoundRectangle(New Rectangle(left, top, width, height), angleTopLeft, angleTopRight, angleBottomRight, angleBottomLeft)
    End Function
#End Region

End Module


Public Interface couleurRemplissage
    Sub paint(ByVal graphics As Graphics, ByVal zone As Rectangle)
    Sub paint(ByVal graphics As Graphics, ByVal zone As Rectangle, ByVal masque As GraphicsPath)
End Interface
Public Class CouleurDegrade
    Protected _couleur1 As Color
    Protected _couleur2 As Color
    Public Sub New(ByVal couleur1 As Color, ByVal couleur2 As Color)
        _couleur1 = couleur1
        _couleur2 = couleur2
    End Sub
    Public Property couleur1() As Color
        Get
            Return _couleur1
        End Get
        Set(ByVal value As Color)
            _couleur1 = value
        End Set
    End Property
    Public Property couleur2() As Color
        Get
            Return _couleur2
        End Get
        Set(ByVal value As Color)
            _couleur2 = value
        End Set
    End Property
End Class
Public Class remplissageDoubleDegrade
    Implements couleurRemplissage
    Protected _degrade1 As CouleurDegrade
    Protected _degrade2 As CouleurDegrade
    Protected _lgnDemarquation As Integer
    Public Sub New(ByVal degrade1 As CouleurDegrade, ByVal degrade2 As CouleurDegrade, ByVal lgnDemarquation As Integer)
        _degrade1 = degrade1
        _degrade2 = degrade2
        _lgnDemarquation = lgnDemarquation
    End Sub
    Public Property degrade1() As CouleurDegrade
        Get
            Return _degrade1
        End Get
        Set(ByVal value As CouleurDegrade)
            _degrade1 = value
        End Set
    End Property
    Public Property degrade2() As CouleurDegrade
        Get
            Return _degrade2
        End Get
        Set(ByVal value As CouleurDegrade)
            _degrade2 = value
        End Set
    End Property
    Public Property lgnDemarquation() As Integer
        Get
            Return _lgnDemarquation
        End Get
        Set(ByVal value As Integer)
            _lgnDemarquation = value
        End Set
    End Property
    Public Sub paint(ByVal graphics As Graphics, ByVal zone As Rectangle) Implements couleurRemplissage.paint
        PaintDoubleDegrade(graphics, zone, _
                   _degrade1.couleur1, _
                   _degrade1.couleur2, _
                   _degrade2.couleur1, _
                   _degrade2.couleur2, _
                   Nothing, _
                   _lgnDemarquation)
        graphics.DrawLine(New Pen(Color.White, 1), zone.Left, zone.Top, zone.Right, zone.Top)
        graphics.DrawLine(New Pen(Color.White, 1), zone.Left, zone.Top, zone.Left, zone.Bottom)
    End Sub
    Public Sub paint(ByVal graphics As System.Drawing.Graphics, ByVal zone As System.Drawing.Rectangle, ByVal masque As GraphicsPath) Implements couleurRemplissage.paint
        PaintDoubleDegrade(graphics, zone, _
                   _degrade1.couleur1, _
                   _degrade1.couleur2, _
                   _degrade2.couleur1, _
                   _degrade2.couleur2, _
                   masque, _
                   _lgnDemarquation)
    End Sub
End Class


Public Class styleBordure

    Protected _lpen As Pen

    Public Sub New(ByVal pen As Pen)
        _lpen = pen
    End Sub

    Public Property pen() As Pen
        Get
            Return _lpen
        End Get
        Set(ByVal value As Pen)
            _lpen = value
        End Set
    End Property

    Public Sub paint(ByVal graphics As Graphics, ByVal zone As Rectangle)
        graphics.DrawLine(pen, zone.Left, _
                zone.Bottom - 1, zone.Right - 1, _
                zone.Bottom - 1)
        graphics.DrawLine(pen, zone.Right - 1, _
            zone.Top, zone.Right - 1, _
            zone.Bottom - 1)
    End Sub

End Class
